﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Boom.GameObjects;
using Boom.Navigation;

namespace Boom.Navigation
{
    public class GameWorld:GameBasic
    {
        private Player _Player;
        private ListBoom _Booms;
        private ListMonster _Monsters;
        private ListBrick _Bricks;
        private ListItem _Items;
        private CheckKeyBoard _KeyBoard;
        private Background _Background;
        private FileMap _FileMap;
        private Info _Info;
        private SkillBoss _SkillBoss;
        private MonsterBoss _Boss;

        public Info SceneInfo
        {
            get { return _Info; }
            set { _Info = value; }
        }

        public GameWorld(Game Mygame, ref List<Texture2D> ListTexture, string FileName, Info newInfo)
            : base(Mygame)
        {
            _Info = newInfo;

            //Map được đọc
            _FileMap = new FileMap(FileName);

            //Phím
            _KeyBoard = new CheckKeyBoard(Mygame);
            Component.Add(_KeyBoard);

            //Boom Texture 
            Texture2D TextureBoom = ListTexture[0];
            Texture2D TextureFire = ListTexture[1];

            //Gạch Texture 
            List<Texture2D> TextureBrickDes = ListTexture.GetRange(2, 3);
            Texture2D TextureBrickNonDes = ListTexture[5];

            //Vật phẩm Texture 
            List<Texture2D> TextureItem = ListTexture.GetRange(6, 4);

            //Quái vật Texture 
            List<Texture2D> TextureMonster = ListTexture.GetRange(10, 2);

            //Quái boss Texture 
            Texture2D TextureBoss = ListTexture[12];
            Texture2D TextureFireSkill = ListTexture[13];
            Texture2D TextureSkill = ListTexture[14];

            //Single Texture 
            Texture2D TextureBackground = ListTexture[15];
            Texture2D TexturePlayer = ListTexture[16];


            _Bricks = new ListBrick(Mygame, ref TextureBrickDes, ref TextureBrickNonDes, _FileMap.PosDesBricks, _FileMap.TypeDesBricks, _FileMap.PosNonBricks, _FileMap.TypeNonDesBricks);
            _Booms = new ListBoom(Mygame, ref TextureBoom, ref TextureFire, _KeyBoard, _Bricks.PositionBrick, 2);
            _Monsters = new ListMonster(Mygame, _FileMap.PosMonsterLv1, _FileMap.PosMonsterLv2, ref TextureMonster);
            _Items = new ListItem(Mygame, ref TextureItem, _FileMap.PosDesBricks, _FileMap.PosDesBricks.Count / 3);
            _Background = new Background(Mygame, ref TextureBackground);
            _Player = new Player(Mygame, _FileMap.PosPlayer, Config.DefaultHpPlayer, ref TexturePlayer, _KeyBoard);
            if (_FileMap.Boss)
            {
                _Boss = new MonsterBoss(Mygame, ref TextureBoss, _FileMap.PosBoss);
                _SkillBoss = new SkillBoss(Mygame, ref TextureSkill, ref TextureFireSkill, false);
            }

            Component.Add(_Background);
            Component.Add(_Booms);
            Component.Add(_Items);
            Component.Add(_Bricks);
            Component.Add(_Monsters);
            Component.Add(_Player);
            if (_FileMap.Boss)
            {
                Component.Add(_SkillBoss);
                Component.Add(_Boss);
            }
        }

        //Lấy thông tin màn chơi
        private void SetInfo()
        {
            _Info.InfLive = _Player.HP;
            _Info.InfScore = _Monsters.List.Count;
            _Info.InfMaxBoom = _Booms.MaxBoom;
            _Info.InfLenght = _Booms.Lenght;
        }

        //Xét va chạm của 2 vật
        private bool Collision(Rectangle Rect1, Rectangle Rect2)
        {
            return (Rect1.X + Rect1.Width > Rect2.X && Rect1.X < Rect2.X + Rect2.Width && Rect1.Y + Rect1.Height > Rect2.Y && Rect1.Y < Rect2.Y + Rect2.Height);
        }

        //Xét hướng va chạm quái vật với gạch 
        //Xử lý va chạm
        private Vector2 Resolve_Collision(int VectorA, Vector2 Pos1, Vector2 Pos2)
        {
            Vector2 PosTemp = Pos1;

            if (VectorA == 3) PosTemp.X = Pos2.X - 40;
            if (VectorA == 4) PosTemp.Y = Pos2.Y - 40;
            if (VectorA == 1) PosTemp.X = Pos2.X + 40;
            if (VectorA == 2) PosTemp.Y = Pos2.Y + 40;

            return PosTemp;
        }

        //Xét va chạm của gạch với quái vật
        private void Collision_Brick()
        {
            for (int i = 0; i < _Bricks.List.Count; i++)
            {     
                //va chạm với quái vật
                for (int j = 0; j < _Monsters.List.Count; j++)
                {
                    if (Collision(_Monsters.List[j].Bounds, _Bricks.List[i].Bounds) && _Monsters.List[j].Level == 1)
                    {
                        int VectorA = _Monsters.List[j].VectorA;
                        Vector2 PosMons = _Monsters.List[j].Position;
                        _Monsters.List[j].Position = Resolve_Collision(VectorA, PosMons, _Bricks.List[i].Position);
                        _Monsters.List[j].Move = false;
                    }
                }
            }
        }

        //Phương thức sét trạng thái của người chơi
        //Nhân vật va chạm với gạch và boom
        private void Collision_Player()
        {
            //Va chạm với gạch
            for (int i = 0; i < _Bricks.List.Count; i++)
            {

                if (Collision(_Player.TopLeft, _Bricks.List[i].Bounds))
                {
                    _Player.ColTopLeft = true;
                }
                if (Collision(_Player.TopRight, _Bricks.List[i].Bounds))
                {
                    _Player.ColTopRight = true;
                }
                if (Collision(_Player.BotRight, _Bricks.List[i].Bounds))
                {
                    _Player.ColBotRight = true;
                }
                if (Collision(_Player.BotLeft, _Bricks.List[i].Bounds))
                {
                    _Player.ColBotLeft = true;
                }

            }

            //Va chạm với boom
            for (int j = 0; j < _Booms.List.Count; j++)
            {
                if (!Collision(_Player.Bounds, _Booms.List[j].Bounds))
                {
                    if (Collision(_Player.TopLeft, _Booms.List[j].Bounds))
                    {
                        _Player.ColTopLeft = true;
                    }
                    if (Collision(_Player.TopRight, _Booms.List[j].Bounds))
                    {
                        _Player.ColTopRight = true;
                    }
                    if (Collision(_Player.BotRight, _Booms.List[j].Bounds))
                    {
                        _Player.ColBotRight = true;
                    }
                    if (Collision(_Player.BotLeft, _Booms.List[j].Bounds))
                    {
                        _Player.ColBotLeft = true;
                    }
                }
            }
        }

        //Xét va chạm của quái vật với người chơi
        private void Collision_Monster_Player(GameTime gameTime)
        {
            for (int i = 0; i < _Monsters.List.Count; i++)
            {
                _Monsters.List[i].Target = _Player.Position;
                if (Collision(_Monsters.List[i].Bounds, _Player.Bounds) && !_Player.Immortal)
                {
                    if (_Player.HP > 1)
                    {
                        _Player.Status = 1;
                    }

                    else
                    {
                        _Player.Status = 0;
                    }
                }
            }
        }

        //Xét va chạm của item với người chơi
        private void Collision_Item()
        {
            //va chạm với người chơi
            for (int i = 0; i < _Items.List.Count; i++)
            {
                if (Collision(_Player.Bounds,_Items.List[i].Bounds) && _Items.List[i].Enabled)
                {
                    int Type = _Items.List[i].Type;
                    switch (Type)
                    {
                        case 0: 
                            _Booms.MaxBoom++;
                            break;
                        case 1:
                            _Player.HP++;
                            break;
                        case 2:
                            _Booms.Lenght++;
                            break;
                        case 3:
                            if (_Player.Status != 3)
                                _Player.Status = 4;
                            break;

                    }
                    _Items.List[i].Enabled = false;
                    _Items.List.RemoveAt(i);
                }
            }
        }

        //Xét va chạm của boom với người chơi và quái vật
        private void Collision_Boom(ListBoom Booms)
        {
            Booms.Position = _Player.Position;
            Booms.PositionBrick = _Bricks.PositionBrick;

            for (int i = 0; i < Booms.List.Count; i++)
            {
                //Va chạm với quái vật
                for (int j = 0; j < _Monsters.List.Count; j++)
                {
                    //Lửa của boom sau khi nổ va chạm với quái vật
                    if ((Collision(Booms.List[i].ListFires.HoriFire, _Monsters.List[j].Bounds) || Collision(Booms.List[i].ListFires.VertiFire, _Monsters.List[j].Bounds))
                        && Booms.List[i].FinishTimeBoom)
                    {
                        if (_Monsters.List[j].HP > 1)
                        {
                            _Monsters.List[j].Status = 1;
                        }
                        else
                        {
                            _Monsters.List[j].Status = 0;
                        }
                    }

                    //Boom va chạm với quái vật
                    if (Collision(_Monsters.List[j].Bounds, Booms.List[i].Bounds) && _Monsters.List[j].Level == 1)
                    {
                        _Monsters.List[j].Move = false;
                        _Monsters.List[j].Position = Resolve_Collision(_Monsters.List[j].VectorA, _Monsters.List[j].Position, Booms.List[i].Position);
                    }

                  
                }

                //Lửa va chạm với gạch
                for (int k = 0; k < _Bricks.List.Count; k++)
                {
                    if ((Collision(Booms.List[i].ListFires.HoriFire, _Bricks.List[k].Bounds) ||
                        Collision(Booms.List[i].ListFires.VertiFire, _Bricks.List[k].Bounds)) && _Bricks.List[k].Destroy && Booms.List[i].FinishTimeBoom)
                    {
                        if (!_Bricks.List[k].Remove)
                        {
                            int Result = _Bricks.PositionBrick.BinarySearch((int)_Bricks.List[k].Position.X / 40 + (int)_Bricks.List[k].Position.Y / 40 * 15);
                            _Bricks.PositionBrick.RemoveAt(Result);
                        }
                        _Bricks.List[k].Remove = true;
                    }
                }


                //Lửa va cham với người chơi
                if ((Collision(Booms.List[i].ListFires.HoriFire, _Player.Bounds) || Collision(Booms.List[i].ListFires.VertiFire, _Player.Bounds)) &&
                    Booms.List[i].FinishTimeBoom)
                {
                    if (_Player.HP > 1)
                    {
                        _Player.Status = 1;
                    }
                    else
                    {
                        if (_Player.HP == 1 && _Player.ChangeFrame)
                        {
                            _Player.HP++;
                            _Player.Status = 1;
                        }
                        else
                            _Player.Status = 0;
                    }                    

                }

                //Lửa va chạm với vật phẩm
                for (int k = 0; k < _Items.List.Count; k++)
                {
                    Vector2 PosItem = _Items.List[k].Position;
                    Vector2 PosBoom=Booms.List[i].Position;
                    if((PosItem.Y==PosBoom.Y && PosItem.X>=Booms.List[i].ListFires.HoriFire.X-3 && PosItem.X < Booms.List[i].ListFires.HoriFire.X + Booms.List[i].ListFires.HoriFire.Width) ||
                        (PosItem.X==PosBoom.X && PosItem.Y>=Booms.List[i].ListFires.VertiFire.Y-3 && PosItem.Y <Booms.List[i].ListFires.VertiFire.Y + Booms.List[i].ListFires.VertiFire.Height))
                    {
                        if (_Items.List[k].Enabled)
                        {
                            _Items.List[k].ElapsedTimeDes = Booms.List[i].ElapsedDisp;
                            _Items.List[k].ShowItem = false;
                        }
                        else
                        {
                            _Items.List[k].ElapsedTimeShow = Booms.List[i].ElapsedDisp;
                            _Items.List[k].ShowItem = true;
                        }
                    }
                }
                
            }
        }

        //Xét riêng cho màn boss
        private void Boss()
        {
            for (int i = 0; i < _SkillBoss.List.Count; i++)
            {
                if ((Collision(_SkillBoss.List[i].ListFires.HoriFire, _Player.Bounds) || Collision(_SkillBoss.List[i].ListFires.VertiFire, _Player.Bounds)) &&
                       _SkillBoss.List[i].FinishTimeBoom)
                {
                    if (_Player.HP > 1)
                    {
                        _Player.Status = 1;
                    }
                    else
                    {
                        if (_Player.HP == 1 && _Player.ChangeFrame)
                        {
                            _Player.HP++;
                            _Player.Status = 1;
                        }
                        else
                            _Player.Status = 0;
                    }

                }
            }

            for (int i = 0; i < _Booms.List.Count; i++)
            {
                if ((Collision(_Booms.List[i].ListFires.HoriFire, _Boss.Bounds) || Collision(_Booms.List[i].ListFires.VertiFire, _Boss.Bounds))
                      && _Booms.List[i].FinishTimeBoom)
                {
                    if (_Boss.HP > 1)
                    {
                        _Boss.Status = 1;
                    }
                    else
                    {
                        _Boss.Status = 0;
                    }
                }
            }
        }

        public override void Update(GameTime gameTime)
        {
            SetInfo();
            Collision_Player();
            Collision_Brick();
            Collision_Monster_Player(gameTime);
            Collision_Item();
            Collision_Boom(_Booms);
            if (_FileMap.Boss)
            {
                Boss();
            }
            base.Update(gameTime);
   
        }
    }
}
